home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Games of Daze
/
Infomagic - Games of Daze (Summer 1995) (Disc 1 of 2).iso
/
x2ftp
/
msdos
/
xlib
/
xlib06
/
xcomppbm.asm
< prev
next >
Wrap
Assembly Source File
|
1993-09-12
|
8KB
|
323 lines
;-----------------------------------------------------------------------
; module XCOMPPBM
;
; This module contains only the compiler and sizeof routines --
; use the plotter from XCBITMAP.
;
;-----------------------------------------------------------------------
include xlib.inc
include xcomppbm.inc
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; _x_compile_pbm
;
; I only changed five instructions, instead of rewriting this
; for PBMs. So it is amazingly inefficient. But, what the hell,
; It's only a game :).
;
; accessory macros to save typing (what else?)
Emitb macro arg
mov byte ptr es:[di],&arg&
inc di
endm
Emitw macro arg
mov word ptr es:[di],&arg&
add di,2
endm
; opcodes emitted by _x_compile_pbm
ROL_AL equ 0c0d0h ; rol al
SHORT_STORE_8 equ 044c6h ; mov [si]+disp8, imm8
STORE_8 equ 084c6h ; mov [si]+disp16, imm8
SHORT_STORE_16 equ 044c7h ; mov [si]+disp8, imm16
STORE_16 equ 084c7h ; mov [si]+disp16, imm16
ADC_SI_IMMED equ 0d683h ; adc si,imm8
OUT_AL equ 0eeh ; out dx,al
RETURN equ 0cbh ; ret
.data
align 2
ColumnMask db 011h,022h,044h,088h
.code
align 2
_x_compile_pbm proc
ARG logical_width:word,bitmap:dword,output:dword
LOCAL bwidth,scanx,scany,outputx,outputy,column,set_column,input_size:word=LocalStk
push bp
mov bp, sp ; caller's stack frame
sub sp,LocalStk ; local space
push si
push di
push ds
mov word ptr [scanx],0
mov word ptr [scany],0
mov word ptr [outputx],0
mov word ptr [outputy],0
mov word ptr [column],0
mov word ptr [set_column],0
lds si,[bitmap] ; 32-bit pointer to source bitmap
les di,[output] ; 32-bit pointer to destination stream
lodsb ; load width byte
xor ah, ah ; convert to word
mov [bwidth], ax ; save for future reference
mov bl, al ; copy width byte to bl
lodsb ; load height byte -- already a word since ah=0
mul bl ; mult height word by width byte
mov [input_size], ax; to get pixel total
@@MainLoop:
mov bx, [scanx] ; position in original bitmap
add bx, [scany]
mov al, [si+bx] ; get pixel
or al, al ; skip empty pixels
jnz @@NoAdvance
jmp @@Advance
@@NoAdvance:
mov dx, [set_column]
cmp dx, [column]
je @@SameColumn
@@ColumnLoop:
Emitw ROL_AL ; emit code to move to new column
Emitw ADC_SI_IMMED
Emitb 0
inc dx
cmp dx, [column]
jl @@ColumnLoop
Emitb OUT_AL ; emit code to set VGA mask for new column
mov [set_column], dx
@@SameColumn:
mov dx, [outputy] ; calculate output position
add dx, [outputx]
sub dx, 128
inc word ptr [scanx]
mov cx, [scanx] ; within four pixels of right edge?
cmp cx, [bwidth]
jge @@OnePixel
inc word ptr [outputx]
mov ah, [si+bx+1] ; get second pixel
or ah, ah
jnz @@TwoPixels
@@OnePixel:
cmp dx, 127 ; can we use shorter form?
jg @@OnePixLarge
cmp dx, -128
jl @@OnePixLarge
Emitw SHORT_STORE_8
Emitb dl ; 8-bit position in output
jmp @@EmitOnePixel
@@OnePixLarge:
Emitw STORE_8
Emitw dx ; position in output
@@EmitOnePixel:
Emitb al
jmp short @@Advance
@@TwoPixels:
cmp dx, 127
jg @@TwoPixLarge
cmp dx, -128
jl @@TwoPixLarge
Emitw SHORT_STORE_16
Emitb dl ; 8-bit position in output
jmp @@EmitTwoPixels
@@TwoPixLarge:
Emitw STORE_16
Emitw dx ; position in output
@@EmitTwoPixels:
Emitw ax
@@Advance:
inc word ptr [outputx]
mov ax, [scanx]
inc ax
cmp ax, [bwidth]
jl @@AdvanceDone
mov dx, [outputy]
add dx, [logical_width]
mov cx, [scany]
add cx, [bwidth]
cmp cx, [input_size]
jl @@NoNewColumn
inc word ptr [column]
mov cx, [column]
cmp cx, 4
je @@Exit ; Column 4: there is no column 4.
xor cx, cx ; scany and outputy are 0 again for
mov dx, cx ; the new column
add si, [input_size]
@@NoNewColumn:
mov [outputy], dx
mov [scany], cx
xor ax, ax
mov word ptr [outputx], 0
@@AdvanceDone:
mov [scanx], ax
jmp @@MainLoop
@@Exit:
Emitb RETURN
mov ax,di
sub ax,word ptr [output] ; size of generated code
pop ds
pop di
pop si
mov sp, bp
pop bp
ret
_x_compile_pbm endp
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; _x_sizeof_cpbm
;
align 2
_x_sizeof_cpbm proc
ARG logical_width:word,bitmap:dword
LOCAL bwidth,scanx,scany,outputx,outputy,column,set_column,input_size:word=LocalStk
push bp
mov bp, sp ; caller's stack frame
sub sp,LocalStk ; local space
push si
push di
push ds
mov word ptr [scanx], 0
mov word ptr [scany], 0
mov word ptr [outputx], 0
mov word ptr [outputy], 0
mov word ptr [column], 0
mov word ptr [set_column], 0
lds si,[bitmap] ; 32-bit pointer to source bitmap
mov di, 1 ; initial size is just the size of the far RET
lodsb ; load width byte
xor ah, ah ; convert to word
mov [bwidth], ax ; save for future reference
mov bl, al ; copy width byte to bl
lodsb ; load height byte -- already a word since ah=0
mul bl ; mult height word by width byte
mov [input_size], ax; to get pixel total
@@MainLoop:
mov bx, [scanx] ; position in original bitmap
add bx, [scany]
mov al, [si+bx] ; get pixel
or al, al ; skip empty pixels
jnz @@NoAdvance
jmp @@Advance
@@NoAdvance:
mov dx, [set_column]
cmp dx, [column]
je @@SameColumn
@@ColumnLoop:
add di, 5 ; size of code to move to new column
inc dx
cmp dx,[column]
jl @@ColumnLoop
inc di ; size of code to set VGA mask
mov [set_column], dx
@@SameColumn:
mov dx, [outputy] ; calculate output position
add dx, [outputx]
sub dx, 128
inc word ptr [scanx]
mov cx, [scanx] ; within four pixels of right edge?
cmp cx, [bwidth]
jge @@OnePixel
inc word ptr [outputx]
mov ah,[si+bx+1] ; get second pixel
or ah, ah
jnz @@TwoPixels
@@OnePixel:
cmp dx, 127 ; can we use shorter form?
jg @@OnePixLarge
cmp dx, -128
jl @@OnePixLarge
add di, 4 ; size of 8-bit position in output plus one pixel
jmp @@EmitOnePixel
@@OnePixLarge:
add di, 5 ; size of position in output plus one pixels
@@EmitOnePixel:
jmp short @@Advance
@@TwoPixels:
cmp dx, 127
jg @@TwoPixLarge
cmp dx, -128
jl @@TwoPixLarge
add di, 5 ; size of 8-bit position in output plus two pixels
jmp @@EmitTwoPixels
@@TwoPixLarge:
add di, 6 ; size of 16-bit position in output plus two pixels
@@EmitTwoPixels:
@@Advance:
inc word ptr [outputx]
mov ax, [scanx]
inc ax
cmp ax, [bwidth]
jl @@AdvanceDone
mov dx, [outputy]
add dx, [logical_width]
mov cx, [scany]
add cx, [bwidth]
cmp cx, [input_size]
jl @@NoNewColumn
inc word ptr [column]
mov cx, [column]
cmp cx, 4
je @@Exit ; Column 4: there is no column 4.
xor cx,cx ; scany and outputy are 0 again for
mov dx,cx ; the new column
add si, [input_size]
@@NoNewColumn:
mov [outputy], dx
mov [scany], cx
xor ax, ax
mov word ptr [outputx], ax
@@AdvanceDone:
mov [scanx], ax
jmp @@MainLoop
@@Exit:
mov ax, di ; size of generated code
pop ds
pop di
pop si
mov sp,bp
pop bp
ret
_x_sizeof_cpbm endp
end